home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / comm / tcp / Amster.lha / Amster_Install / Source / chat.c < prev    next >
C/C++ Source or Header  |  2000-07-20  |  10KB  |  363 lines

  1. /*
  2. ** Chat Window
  3. */
  4.  
  5. #include "include/config.h"
  6.  
  7. #include <stdio.h>
  8. #include <stdarg.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11.  
  12. #include "include/mui.h"
  13. #include <MUI/NListview_mcc.h>
  14.  
  15. #include "include/gui.h"
  16. #include "include/msg.h"
  17. #include "include/channellist.h"
  18. #include "include/chat.h"
  19. #include "include/panel.h"
  20. #include "include/prefs.h"
  21. #include "include/napster.h"
  22. #include "include/protos.h"
  23. #include "amster_Cat.h"
  24.  
  25. channel chat_chans = NULL;
  26.  
  27. ULONG chat_new(struct IClass *cl, Object *obj, struct opSet *msg);
  28. MUIF chat_msgdisp(REG(a2) char **array, REG(a1) struct ChatMessage *m);
  29. void channel_part(struct chatdata *data);
  30. void chat_say(struct chatdata *data, char *user, char *msg);
  31. void chat_sayf(struct chatdata *data, char *user, char *msg, ...);
  32. void chat_saysys(struct chatdata *data, char *msg);
  33. void chat_echo(struct chatdata *data, char *msg);
  34. void chat_command(struct chatdata *data);
  35.  
  36.  
  37. MUIF chat_dispatch(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  38. {
  39.     struct chatdata *data;
  40.  
  41.     switch(msg->MethodID) {
  42.         case OM_NEW:
  43.             return(chat_new(cl, obj, (APTR)msg));
  44.         case CHAT_COMMAND:
  45.             data = INST_DATA(cl, obj);
  46.             chat_command(data);
  47.             return(0);
  48.         case CHAT_JOINCHANNEL:
  49.             data = INST_DATA(cl, obj);
  50.             if (gui_onlinestate < ONLINE) chat_saysys(data, (char *)MSG_CHAT_NOTCONNECTED);
  51.             else {
  52.                 data->chn.name = strdup((char *)(((muimsg)msg)->arg1));
  53.                 nap_sendbuf(NAPC_CHANNELJOIN, data->chn.name);
  54.                 data->chn.joinflag = 1;
  55.             }
  56.             return(0);
  57.         case CHAT_JOINACK:
  58.             data = INST_DATA(cl, obj);
  59.             data->chn.joinflag = 2;
  60.             DoMethod(data->rect, MUIM_Group_InitChange);
  61.             set(data->chantxt, MUIA_Text_Contents, data->chn.name);
  62.             DoMethod(data->rect, MUIM_Group_ExitChange);
  63.             chat_sayf(data,"\33b-->", (char *)MSG_CHAT_JOINED_YOU, data->chn.name);
  64.             return(0);
  65.         case CHAT_PUBLICMSGRECV:
  66.             data = INST_DATA(cl, obj);
  67.             if (stricmp(prf->user, (char *)(((muimsg)msg)->arg1)) != 0)
  68.                 chat_say(data, (char *)(((muimsg)msg)->arg1), (char *)(((muimsg)msg)->arg2));
  69.                 /* Only show messages from others */
  70.             return(0);
  71.         case CHAT_JOINMSG:
  72.             data = INST_DATA(cl, obj);
  73.             chat_sayf(data, "\33b-->", (char *)MSG_CHAT_JOINED_THIS, (char *)(((muimsg)msg)->arg1), (int)(((muimsg)msg)->arg2), nap_linktype[(int)(((muimsg)msg)->arg3)]);
  74.         case CHAT_USERLIST:
  75.             data = INST_DATA(cl, obj);
  76.             /* TODO: Use the ChannelUserData struct and create a display book for the userlist */
  77.             DoMethod(data->userlist, MUIM_NList_InsertSingle, (char *)(((muimsg)msg)->arg1), MUIV_NList_Insert_Bottom);
  78.             return(0);
  79.         case CHAT_USERPART:
  80.             {
  81.             int i;
  82.             char *cuser;
  83.             data = INST_DATA(cl, obj);
  84.  
  85.             chat_sayf(data,"\33b<--", (char *)MSG_CHAT_PART_THIS, (char *)(((muimsg)msg)->arg1));
  86.  
  87.             for (i=0; ; i++) {
  88.                 DoMethod(data->userlist, MUIM_NList_GetEntry, i, &cuser);
  89.                 if (!cuser) break;
  90.                 if (strcmp((char *)(((muimsg)msg)->arg1), cuser) == 0) {
  91.                     DoMethod(data->userlist, MUIM_NList_Remove, i);
  92.                     break;
  93.                 }
  94.             }
  95.  
  96.             return(0);
  97.             }
  98.         case CHAT_CHANNELPART:
  99.             data = INST_DATA(cl, obj);
  100.             if (data->chn.name) nap_sendbuf(NAPC_CHANNELPART, data->chn.name);
  101.             DoMethod(gui->iconpanel, PANEL_DISPOSECHAT, obj);
  102.             return(0);
  103.         case CHAT_CHANNELTOPIC:
  104.             data = INST_DATA(cl, obj);
  105.             set(data->topicstr, MUIA_String_Contents, ((muimsg)msg)->arg1);
  106.             return(0);
  107.  
  108.     }
  109.     return(DoSuperMethodA(cl, obj, msg));
  110. }
  111.  
  112.  
  113. ULONG chat_new(struct IClass *cl, Object *obj, struct opSet *msg)
  114. {
  115.     static struct Hook msgdispHook = { {0,0}, &chat_msgdisp, NULL, NULL };
  116.     struct chatdata *data;
  117.     Object *rect, *chantxt, *topicstr, *msglist, *userlist, *msgstr;
  118.  
  119.     obj = (Object *)DoSuperNew(cl, obj,
  120.         MUIA_HelpNode, "chat",
  121.         MUIA_Window_Title, MSG_CHAT_TITLE,
  122.         MUIA_Window_ID, MAKE_ID('C','H','A','T'),
  123.         WindowContents, VGroup,
  124.             Child, rect = HGroup,
  125.                 Child, chantxt = TextObject,
  126.                     MUIA_HorizWeight, 0,
  127.                     MUIA_Text_Contents, MSG_CHAT_NONEJOINED,
  128.                 End,
  129.                 Child, topicstr = StringObject,
  130.                     StringFrame,
  131.                     MUIA_CycleChain, 1,
  132.                 End,
  133.             End,
  134.             Child, HGroup,
  135.                 Child, NListviewObject,
  136.                     MUIA_HorizWeight, 75,
  137.                     MUIA_NListview_NList, msglist = NListObject,
  138.                         ReadListFrame,
  139.                         MUIA_NList_Input, FALSE,
  140.                         MUIA_NList_Format, "BAR P=\33r,",
  141.                         MUIA_NList_DisplayHook, &msgdispHook,
  142.                         MUIA_NList_DefaultObjectOnClick, FALSE,
  143.                         MUIA_NList_AutoVisible, TRUE,
  144.                         MUIA_NList_AutoCopyToClip, TRUE,
  145.                         MUIA_NList_TypeSelect, MUIV_NList_TypeSelect_Char,
  146.                     End,
  147.                 End,
  148.                 Child, BalanceObject, End,
  149.                 Child, NListviewObject,
  150.                     MUIA_HorizWeight, 25,
  151.                     MUIA_NListview_NList, userlist = NListObject,
  152.                         InputListFrame,
  153.                         MUIA_NList_DefaultObjectOnClick, FALSE,
  154.                         MUIA_NList_ConstructHook, MUIV_NList_ConstructHook_String,
  155.                         MUIA_NList_DestructHook, MUIV_NList_DestructHook_String,
  156.                         MUIA_CycleChain, 1,
  157.                     End,
  158.                 End,
  159.             End,
  160.             Child, msgstr = StringObject,
  161.                 StringFrame,
  162.                 MUIA_CycleChain, 1,
  163.             End,
  164.         End,
  165.         TAG_MORE, msg->ops_AttrList);
  166.  
  167.     if (!obj) return(0);
  168.  
  169.     data = INST_DATA(cl,obj);
  170.     data->rect = rect;
  171.     data->chantxt = chantxt;
  172.     data->topicstr = topicstr;
  173.     data->msglist = msglist;
  174.     data->userlist = userlist;
  175.     data->msgstr = msgstr;
  176.  
  177.     data->chn.next = chat_chans;
  178.     chat_chans = &data->chn;
  179.     data->chn.joinflag = 0;
  180.     data->chn.name = NULL;
  181.     data->chn.win = obj;
  182.  
  183.     DoMethod(msgstr, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, obj, 1, CHAT_COMMAND);
  184.     DoMethod(msgstr, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, obj, 3, MUIM_Set, MUIA_Window_ActiveObject, msgstr);
  185.  
  186.     DoMethod(obj, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, MUIV_Notify_Application, 5, MUIM_Application_PushMethod, obj, 1, CHAT_CHANNELPART);
  187. /*    DoMethod(obj, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, MUIV_Notify_Application, 5, MUIM_Application_PushMethod, gui->iconpanel, 2, PANEL_DISPOSECHAT, obj);*/
  188.  
  189.     return((ULONG)obj);
  190. }
  191.  
  192.  
  193. MUIF chat_msgdisp(REG(a2) char **array, REG(a1) struct ChatMessage *m)
  194. {
  195.     *array++ = m->Nick;
  196.     *array = m->Msg;
  197.  
  198.     return(0);
  199. }
  200.  
  201.  
  202. void chat_say(struct chatdata *data, char *user, char *msg)
  203. {
  204.     struct ChatMessage *m;
  205.  
  206.     m = malloc(sizeof(struct ChatMessage));
  207.     if (!m) return;
  208.  
  209.     m->Nick = strdup(user);
  210.     m->Msg = strdup(msg);
  211.  
  212.     DoMethod(data->msglist, MUIM_NList_InsertSingleWrap, m, MUIV_NList_Insert_Bottom, 2, NULL);
  213.     set(data->msglist, MUIA_NList_First, MUIV_NList_Active_Bottom);
  214. }
  215.  
  216.  
  217. void chat_sayf(struct chatdata *data, char *user, char *msg, ...)
  218. {
  219.     static char buf[1024];
  220.     va_list ap;
  221.  
  222.     va_start(ap, msg);
  223.     vsprintf(buf, msg, ap);
  224.     va_end(ap);
  225.     chat_say(data, user, buf);
  226. }
  227.  
  228.  
  229. void chat_saysys(struct chatdata *data, char *msg)
  230. {
  231.     chat_say(data,"\33b***",msg);
  232. }
  233.  
  234.  
  235. void chat_echo(struct chatdata *data, char *msg)
  236. {
  237.     chat_say(data,"\33b»",msg);
  238. }
  239.  
  240.  
  241. void chat_command(struct chatdata *data)
  242. {
  243.     u_long tmp;
  244.     char *com;
  245.  
  246.     GetAttr(MUIA_String_Contents, data->msgstr, &tmp);
  247.     com = (char *)tmp;
  248.  
  249.     if (com[0] == '/') {
  250.         if (strnicmp("join", com+1, 4) == 0 && strlen(com)>6) {
  251.             if (gui_onlinestate < ONLINE) chat_saysys(data, (char *)MSG_CHAT_NOTCONNECTED);
  252.             else {
  253.                 if (data->chn.name) channel_part(data);
  254.                 /* Leave channel in this window before joining a new one. */
  255.  
  256.                 data->chn.name = strdup(com+6);
  257.                 nap_sendbuf(NAPC_CHANNELJOIN, data->chn.name);
  258.                 data->chn.joinflag = 1;
  259. /*                chat_saysys(data,"joining...");*/
  260.             }
  261.         }
  262.         else if (stricmp("leave", com+1) == 0) {
  263.             if (gui_onlinestate < ONLINE) chat_saysys(data, (char *)MSG_CHAT_NOTCONNECTED);
  264.             else channel_part(data);
  265.         }
  266.         else if (stricmp("list", com+1) == 0) {
  267.             DoMethod(gui->WI_ChannelList, MUIM_Set, MUIA_Window_Open, TRUE);
  268.             if (gui_onlinestate == ONLINE) DoMethod(gui->WI_ChannelList, CHANLIST_UPDATE);
  269.         }
  270.  
  271.     }
  272.     else {
  273.         if (gui_onlinestate < ONLINE) chat_saysys(data, (char *)MSG_CHAT_NOTCONNECTED);
  274.         else {
  275.             if (data->chn.joinflag>1) {
  276. /*                chat_echo(data,com);*/
  277.                 chat_say(data, prf->user, com);
  278.                 sprintf(nap_buf,"%s %s", data->chn.name, com);
  279.                 nap_send(NAPC_PUBLICMSGSEND);
  280.             }
  281.             else {
  282.                 chat_saysys(data, (char *)MSG_CHAT_NOTJOINED);
  283.             }
  284.         }
  285.     }
  286.  
  287.     set(data->msgstr, MUIA_String_Contents, NULL);
  288. }
  289.  
  290.  
  291. void channel_part(struct chatdata *data)
  292. {
  293.     u_long item;
  294.  
  295.     nap_sendbuf(NAPC_CHANNELPART, data->chn.name);
  296.     chat_sayf(data,"\33b<--", (char *)MSG_CHAT_PART_YOU, data->chn.name);
  297.  
  298.     set(data->userlist, MUIA_NList_Quiet, MUIV_NList_Quiet_Visual);
  299.     while (1) {
  300.         DoMethod(data->userlist, MUIM_NList_GetEntry, 0, &item);
  301.         if (!item) break;
  302.         DoMethod(data->userlist, MUIM_NList_Remove, MUIV_NList_Remove_First);
  303.     }
  304.     set(data->userlist, MUIA_NList_Quiet, MUIV_NList_Quiet_None);
  305.     /* Clear users from list */
  306.  
  307.     set(data->chantxt, MUIA_Text_Contents, MSG_CHAT_NONEJOINED);
  308.     /* Set channel name */
  309. }
  310.  
  311.  
  312. void chat_interpret(u_int com, char *data)
  313. {
  314.     channel c;
  315.  
  316.     switch (com) {
  317.         case NAPC_PUBLICMSGRECV:
  318.             c = chat_findchan(nap_token(&data));
  319.             if (!c) break;
  320.             DoMethod(c->win,CHAT_PUBLICMSGRECV,nap_token(&data),data);
  321.             break;
  322.         case NAPC_JOINACK:
  323.             c = chat_findchan(data);
  324.             if (!c) break;
  325.             DoMethod(c->win,CHAT_JOINACK);
  326.             break;
  327.         case NAPC_USERPART:
  328.             c = chat_findchan(nap_token(&data));
  329.             if (!c) break;
  330.             DoMethod(c->win,CHAT_USERPART,nap_token(&data));
  331.             break;
  332.         case NAPC_JOINMSG:
  333.             c = chat_findchan(nap_token(&data));
  334.             if (!c) break;
  335.             DoMethod(c->win, CHAT_JOINMSG, nap_token(&data), nap_itoken(&data), atoi(data));
  336.             break;
  337.         case NAPC_USERLIST:
  338.             c = chat_findchan(nap_token(&data));
  339.             if (!c) break;
  340.             DoMethod(c->win, CHAT_USERLIST, nap_token(&data), nap_itoken(&data), atoi(data));
  341.             break;
  342.         case NAPC_USERLISTEND:
  343.             break;
  344.         case NAPC_CHANNELTOPIC:
  345.             c = chat_findchan(nap_token(&data));
  346.             if (!c) break;
  347.             DoMethod(c->win, CHAT_CHANNELTOPIC, data);
  348.             break;
  349.     }
  350. }
  351.  
  352.  
  353. channel chat_findchan(char *name)
  354. {
  355.     channel c = chat_chans;
  356.  
  357.     while (c) {
  358.         if (stricmp(c->name, name) == 0) return(c);
  359.         c = c->next;
  360.     }
  361.     return(0);
  362. }
  363.